package com.lcx.nfctest;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import com.lcx.nfctest.database.UserDBHelper;
import com.lcx.nfctest.nfctestinfo.NfcTestInfo;
import com.lcx.nfctest.util.ToastUtil;


public class NfcTestActivity extends AppCompatActivity implements NfcCardReader2.TechCallback, NfcAdapter.OnTagRemovedListener, View.OnClickListener {
    private static final int READER_FLAG = NfcAdapter.FLAG_READER_NFC_A |  NfcAdapter.FLAG_READER_NFC_B| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;;
    String TAG = "lcx_debug";
    protected NfcAdapter mNfcAdapter;
    private PendingIntent mPendingIntent;
    Tag mTag;
    int nfcReadTimes = 0;
    TextView tvTimes ;
    TextView tvTech ;
    TextView tvTagId;
    TextView currentTimeText;
    TextView tvQueryAllRecord;
    Button btnTimeReset;
    Button btnDeleteDatabase;
    Button btnDeleteAllRecord;
    Button btnQueryAllRecord;
    NfcCardReader2 mNfcCardReader;
    private static UserDBHelper mHelper;
    private final int mDBOperationInsert = 0x01;
    private final int mDBOperationDeleteAll = 0x02;
    private final int mDBOperationQuaryAll = 0x03;
    private static Context ctx;
    private String bootTime;
    private String tagId;
    NfcTestInfo nfcTestInfo = new NfcTestInfo();


    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            Log.d(TAG, "handleMessage:");
            switch (msg.what){
                case mDBOperationInsert:
                    if (dbInsert() < 0) {
                        ToastUtil.show(ctx, "读卡数据数据库写入失败");
                        Log.e(TAG, "handleMessage: dbInsert indsert failed");
                    }
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(ctx, "读卡数据写入数据库成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                    Log.d(TAG, "handleMessage: dbInsert indsert succeeded");
                    break;
                case mDBOperationDeleteAll:
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if(mHelper.deleteAllRecord() < 0) {
                                ToastUtil.show(ctx, "删除测试记录失败");
                                Log.e(TAG, "handleMessage: dbDleteAllrecord failed");
                            }
                            tvQueryAllRecord.setText(null);
                            Toast.makeText(ctx, "删除表中所有测试记录成功", Toast.LENGTH_SHORT).show();
                            Log.d(TAG, "handleMessage: dbDleteAllrecord succeeded");
                        }
                    });
                    break;

                case mDBOperationQuaryAll:
                    tvQueryAllRecord = findViewById(R.id.tv_quary_result_show);
                    List<NfcTestInfo> list = mHelper.queryAllRecord();
                    Log.d(TAG, "quary result num :" + list.size());
                    StringBuilder queryAllRecord = new StringBuilder();
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            if (list.size() <= 0) {
                                ToastUtil.show(ctx, "查询测试记录为空或者失败");
                                Log.e(TAG, "handleMessage: dbQuaryAllrecord failed");
                                return;
                            }
                            ToastUtil.show(ctx,"查询到 " + list.size() + " 条测试记录");
                            for (NfcTestInfo nfcTestInfo : mHelper.queryAllRecord())
                                queryAllRecord.append(nfcTestInfo.toString());

                                //Log.e(TAG, "queryAllRecord: " + nfcTestInfo.toString());
                            }


                    });
                    tvQueryAllRecord.setText(queryAllRecord.toString());
                    Log.e(TAG, "queryAllRecord: "+ queryAllRecord.toString());
                    break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
//        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.tv_times), (v, insets) -> {
//            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
//            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
//            return insets;
//        });
        dataBaseInit();
        initBuildVersion();
        initNfc();
        ctx = getApplicationContext();


    }

    private void dataBaseInit() {
        Context context = this;
        File databaseFile = context.getDatabasePath("NfcTest.db");
        String dataBasePath = databaseFile.getAbsolutePath();
        // 打印数据库文件的路径
        Log.i("DatabasePath", dataBasePath);
        SQLiteDatabase db = openOrCreateDatabase(dataBasePath, Context.MODE_PRIVATE, null);
        String desc = String.format("数据库%s创建%s",db.getPath(),(db != null) ? "成功" : "失败");
        Log.d(TAG, "dataBaseInit: "+ desc);
        mHelper = UserDBHelper.getInstance(this);
        mHelper.openReadLink();
        mHelper.openWriteLink();

    }

    public boolean clearDatabase(String name) {
        boolean result = deleteDatabase(name);
        //TODO 数据库路径不对
        if(result)
            Log.d(TAG, "deleteDatabase: 数据库删除成功");
        else
            Log.d(TAG, "deleteDatabase: 数据库删除失败");
        return result;
    }

    private void initBuildVersion() {
        currentTimeText = findViewById(R.id.tv_build_time);
        bootTime = getCurrentTime();
        currentTimeText.setText(bootTime);
    }

    public static String getCurrentTime() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        Date date = new Date();
        return dateFormat.format(date);
    }

    public void initNfc() {
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);//设备的NfcAdapter对象
        if (mNfcAdapter == null) {//判断设备是否支持NFC功能
            Toast.makeText(this, "设备不支持NFC功能!", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        if (!mNfcAdapter.isEnabled()) {//判断设备NFC功能是否打开
            Toast.makeText(this, "到系统设置中打开NFC功能!", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Settings.ACTION_NFC_SETTINGS);
            startActivity(intent);
            //finish();
            return;
        }
        //mNfcAdapter.enableReaderMode();
        mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()), PendingIntent.FLAG_IMMUTABLE);
        //mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
       //mNfcAdapter.disableNdefPush();
        mNfcCardReader = new NfcCardReader2(this);
        mNfcAdapter.disableReaderMode(NfcTestActivity.this);
        mNfcAdapter.enableReaderMode(NfcTestActivity.this, mNfcCardReader, READER_FLAG, null);
        tvTimes = findViewById(R.id.tv_times);
        tvTagId = findViewById(R.id.tv_tag_id);
        tvTech = findViewById(R.id.tv_tech);

        btnDeleteDatabase = findViewById(R.id.btn_save_database);
        btnDeleteDatabase.setOnClickListener((View.OnClickListener) this);

        btnTimeReset = findViewById(R.id.btn_time_reset);
        btnTimeReset.setOnClickListener((View.OnClickListener) this);

        btnDeleteAllRecord = findViewById(R.id.btn_delete_all_record);
        btnDeleteAllRecord.setOnClickListener((View.OnClickListener) this);

        btnQueryAllRecord = findViewById(R.id.btn_quary_all_record);
        btnQueryAllRecord.setOnClickListener((View.OnClickListener) this);
        //mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_IMMUTABLE);//创建PendingIntent对象,当检测到一个Tag标签就会执行此Intent
    }
    public void tv_deal(Tag tag) {
        Random random = new Random(); // 创建Random对象
        int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256)); // 生成随机ARGB颜色
        String [] tech = tag.getTechList();
        tagId = NfcCardReader2.ByteArrayToHexString(tag.getId());
        nfcReadTimes += 1;
        //textLength = findViewById(R.id.text_length);
        String showText = "read " + nfcReadTimes + " times";
        tvTimes.setText(showText);
        tvTimes.setTextColor(color);// 将TextView的颜色设置为随机色
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(ctx, showText, Toast.LENGTH_SHORT).show();
            }
        });
        tvTech.setText(String.valueOf(Arrays.toString(tech)));
        tvTagId.setText(tagId);
        nfcTestInfo.setTagId(tagId);
        Log.e(TAG, "tv_deal: " + nfcReadTimes +" tech: " + Arrays.toString(tech));
    }
    

    @Override
    public void onTechReceived(final Tag tag) {
        Log.d(TAG,"lcx onTechReceived = " + Arrays.toString(tag.getTechList()));
        tv_deal(tag);
        Intent intent = getIntent();
        Log.d(TAG,"lcx intent = " + intent.getAction());
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
            // 处理NDEF格式的数据
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (rawMsgs != null) {
                NdefRecord[] records = ((NdefMessage) rawMsgs[0]).getRecords();
                String message = new String(records[0].getPayload());
                // 处理message的业务逻辑
                Log.d(TAG, "message： " + message);
            }
        } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
            // 处理TAG格式的数据
            //Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            //String id = bytesToHexString(tag.getId());
            // 处理id的业务逻辑
            //Log.d(TAG, "id： " + id);
        }


    }



    @Override
    protected void onNewIntent(Intent intent) {
        //todo  intent NULL ???
        Log.d(TAG, "onNewIntent： "+ intent.getAction());
        super.onNewIntent(intent);
        if (intent.getAction() == "android.intent.action.MAIN") {
            Log.d(TAG, "Intent： action.MAIN return, no count");
            return;
        }



    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv.toUpperCase());
        }
        return stringBuilder.toString();
    }
    /**
     * 获得焦点，按钮可以点击
     */
    @Override
    public void onResume() {
        Log.d(TAG, "onResume: ");
        super.onResume();
        //判断设备NFC功能是否打开
        if (!mNfcAdapter.isEnabled()) {//判断设备NFC功能是否打开
            Toast.makeText(this, "请到系统设置中打开NFC功能!", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Settings.ACTION_NFC_SETTINGS);
            startActivity(intent);
            return;
        }
        //设置处理优于所有其他NFC的处理
        if (mNfcAdapter != null)
            mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
    }

    /**
     * 暂停Activity，界面获取焦点，按钮可以点击
     */
    @Override
    public void onPause() {
        Log.d(TAG, "onPause: ");
        super.onPause();
        //恢复默认状态
        if (mNfcAdapter != null)
            mNfcAdapter.disableForegroundDispatch(this);
    }

    @Override
    public void onStop() {
        Log.d(TAG, "onStop: ");
        super.onStop();
    }
    public long dbInsert(){
        nfcTestInfo.setTime(nfcReadTimes);
        nfcTestInfo.setReadCardStartTime(bootTime);
        nfcTestInfo.setReadCardEndTime(getCurrentTime());
        nfcTestInfo.setTagId(tagId);
        Log.d(TAG, "nfcTestInfo: " + nfcTestInfo.toString());
        return  mHelper.insert(nfcTestInfo);

    }
    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy:  called ");
        mHelper.closeLink();
        super.onDestroy();
    }

    @Override
    //todo
    public void onTagRemoved() {
        Log.e(TAG, "onTagRemoved: ");
    }

    @Override
    public void onClick(View v) {
        Message msg = new Message();
        switch (v.getId()) {
            case R.id.btn_time_reset:
                nfcReadTimes = 0;
                tvTimes.setText(R.string.tv_times);
                Toast.makeText(this, "读卡计数已清0", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "onClick: nfcReadTimes: " + nfcReadTimes);
                break;
            case R.id.btn_save_database:
                if (nfcReadTimes ==0) {
                    Toast.makeText(this, "请先读卡测试后再保存数据", Toast.LENGTH_SHORT).show();
                    return;
                }
                msg.what = mDBOperationInsert;
                handler.sendMessage(msg);
                Log.i(TAG, "activity finish ");
                finish();
                break;
            case R.id.btn_delete_all_record:
                msg.what = mDBOperationDeleteAll;
                handler.sendMessage(msg);
                break;
            case R.id.btn_quary_all_record:
                msg.what = mDBOperationQuaryAll;
                handler.sendMessage(msg);
                break;
        }
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        switch (newConfig.orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                Toast.makeText(this, "横屏", Toast.LENGTH_SHORT).show();
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                Toast.makeText(this, "竖屏", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}